package com.meng.model.upload;

import com.meng.model.PointOfSale;
import com.meng.redis.enumeration.RedisKeyAndSaveDataServiceNameEnum;
import com.meng.util.SpringContextUtils;
import io.netty.buffer.ByteBuf;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;


/**
 * 上传的消费记录
 *
 * @author MENG
 * @version 2018/4/4
 * @see
 */
public class UploadConsumeRecord extends PointOfSale
{
    /**
     * 上传消费记录ID
     */
    private String ucrid;

    /**
     * 交易记录类型
     */
    private String ty;

    /**
     * 终端交易流水号
     */
    private String ttn;

    /**
     * 脱机交易流水号
     */
    private String psn;

    /**
     * 票卡逻辑卡号
     */
    private String icn;

    /**
     * 票卡物理卡号
     */
    private String fcn;

    /**
     * 上次交易设备编号
     */
    private String lpid;

    /**
     * 上次交易日期时间
     */
    private String ltim;

    /**
     * 本次交易设备编号
     */
    private String pid;

    /**
     * 本次交易日期时间
     */
    private String tim;

    /**
     * 交易金额
     */
    private String tf;

    /**
     * 本次余额
     */
    private String bal;

    /**
     * 交易类型
     */
    private String tt;

    /**
     * 附加交易类型
     */
    private String att;

    /**
     * 票卡充值交易次数
     */
    private String crn;

    /**
     * 票卡消费交易次数
     */
    private String xrn;

    /**
     * 交易认证码
     */
    private String tac;

    /**
     * 卡片类型
     */
    private String ctp;

    /**
     * 票价
     */
    private String fee;

    /**
     * 门槛年月
     */
    private String dmon;

    /**
     * 公交门槛计数
     */
    private String bdct;

    /**
     * 地铁门槛计数
     */
    private String mdct;

    /**
     * 联乘门槛计数
     */
    private String udct;

    /**
     * 发卡机构标识码
     */
    private String iins;

    /**
     * 城市代码
     */
    private String area;

    /**
     * 区域卡类型
     */
    private String act;

    /**
     * 区域子码
     */
    private String sare;

    /**
     * 经度
     */
    private String lot;

    /**
     * 纬度
     */
    private String lat;

    /**
     * 消费密钥版本号
     */
    private String ckv;

    /**
     * 消费密钥索引
     */
    private String cki;

    /**
     * 算法标志
     */
    private String asign;

    /**
     * 随机数
     */
    private String rn;

    /**
     * 检索参考号
     */
    private String srf;

    /**
     * 备用
     */
    private String spare;

    /**
     * 收单机构代码
     */
    private String rins;


    public String getUcrid()
    {
        return ucrid;
    }

    public void setUcrid(String ucrid)
    {
        this.ucrid = ucrid;
    }

    public String getTy()
    {
        return ty;
    }

    public void setTy(String ty)
    {
        this.ty = ty;
    }

    public String getTtn()
    {
        return ttn;
    }

    public void setTtn(String ttn)
    {
        this.ttn = ttn;
    }

    public String getPsn()
    {
        return psn;
    }

    public void setPsn(String psn)
    {
        this.psn = psn;
    }

    public String getIcn()
    {
        return icn;
    }

    public void setIcn(String icn)
    {
        this.icn = icn;
    }

    public String getFcn()
    {
        return fcn;
    }

    public void setFcn(String fcn)
    {
        this.fcn = fcn;
    }

    public String getLpid()
    {
        return lpid;
    }

    public void setLpid(String lpid)
    {
        this.lpid = lpid;
    }

    public String getLtim()
    {
        return ltim;
    }

    public void setLtim(String ltim)
    {
        this.ltim = ltim;
    }

    public String getPid()
    {
        return pid;
    }

    public void setPid(String pid)
    {
        this.pid = pid;
    }

    public String getTim()
    {
        return tim;
    }

    public void setTim(String tim)
    {
        this.tim = tim;
    }

    public String getTf()
    {
        return tf;
    }

    public void setTf(String tf)
    {
        this.tf = tf;
    }

    public String getBal()
    {
        return bal;
    }

    public void setBal(String bal)
    {
        this.bal = bal;
    }

    public String getTt()
    {
        return tt;
    }

    public void setTt(String tt)
    {
        this.tt = tt;
    }

    public String getAtt()
    {
        return att;
    }

    public void setAtt(String att)
    {
        this.att = att;
    }

    public String getCrn()
    {
        return crn;
    }

    public void setCrn(String crn)
    {
        this.crn = crn;
    }

    public String getXrn()
    {
        return xrn;
    }

    public void setXrn(String xrn)
    {
        this.xrn = xrn;
    }

    public String getTac()
    {
        return tac;
    }

    public void setTac(String tac)
    {
        this.tac = tac;
    }

    public String getCtp()
    {
        return ctp;
    }

    public void setCtp(String ctp)
    {
        this.ctp = ctp;
    }

    public String getFee()
    {
        return fee;
    }

    public void setFee(String fee)
    {
        this.fee = fee;
    }

    public String getDmon()
    {
        return dmon;
    }

    public void setDmon(String dmon)
    {
        this.dmon = dmon;
    }

    public String getBdct()
    {
        return bdct;
    }

    public void setBdct(String bdct)
    {
        this.bdct = bdct;
    }

    public String getMdct()
    {
        return mdct;
    }

    public void setMdct(String mdct)
    {
        this.mdct = mdct;
    }

    public String getUdct()
    {
        return udct;
    }

    public void setUdct(String udct)
    {
        this.udct = udct;
    }

    public String getIins()
    {
        return iins;
    }

    public void setIins(String iins)
    {
        this.iins = iins;
    }

    public String getArea()
    {
        return area;
    }

    public void setArea(String area)
    {
        this.area = area;
    }

    public String getAct()
    {
        return act;
    }

    public void setAct(String act)
    {
        this.act = act;
    }

    public String getSare()
    {
        return sare;
    }

    public void setSare(String sare)
    {
        this.sare = sare;
    }

    public String getLot()
    {
        return lot;
    }

    public void setLot(String lot)
    {
        this.lot = lot;
    }

    public String getLat()
    {
        return lat;
    }

    public void setLat(String lat)
    {
        this.lat = lat;
    }

    public String getCkv()
    {
        return ckv;
    }

    public void setCkv(String ckv)
    {
        this.ckv = ckv;
    }

    public String getCki()
    {
        return cki;
    }

    public void setCki(String cki)
    {
        this.cki = cki;
    }

    public String getAsign()
    {
        return asign;
    }

    public void setAsign(String asign)
    {
        this.asign = asign;
    }

    public String getRn()
    {
        return rn;
    }

    public void setRn(String rn)
    {
        this.rn = rn;
    }

    public String getSrf()
    {
        return srf;
    }

    public void setSrf(String srf)
    {
        this.srf = srf;
    }

    public String getSpare()
    {
        return spare;
    }

    public void setSpare(String spare)
    {
        this.spare = spare;
    }

    public String getRins()
    {
        return rins;
    }

    public void setRins(String rins)
    {
        this.rins = rins;
    }

    @Override
    public String toString()
    {
        return "UploadConsumeRecord{" +
               "ucrid='" + ucrid + '\'' +
               ", ty='" + ty + '\'' +
               ", ttn='" + ttn + '\'' +
               ", psn='" + psn + '\'' +
               ", icn='" + icn + '\'' +
               ", fcn='" + fcn + '\'' +
               ", lpid='" + lpid + '\'' +
               ", ltim='" + ltim + '\'' +
               ", pid='" + pid + '\'' +
               ", tim='" + tim + '\'' +
               ", tf='" + tf + '\'' +
               ", bal='" + bal + '\'' +
               ", tt='" + tt + '\'' +
               ", att='" + att + '\'' +
               ", crn='" + crn + '\'' +
               ", xrn='" + xrn + '\'' +
               ", tac='" + tac + '\'' +
               ", ctp='" + ctp + '\'' +
               ", fee='" + fee + '\'' +
               ", dmon='" + dmon + '\'' +
               ", bdct='" + bdct + '\'' +
               ", mdct='" + mdct + '\'' +
               ", udct='" + udct + '\'' +
               ", iins='" + iins + '\'' +
               ", area='" + area + '\'' +
               ", act='" + act + '\'' +
               ", sare='" + sare + '\'' +
               ", lot='" + lot + '\'' +
               ", lat='" + lat + '\'' +
               ", ckv='" + ckv + '\'' +
               ", cki='" + cki + '\'' +
               ", asign='" + asign + '\'' +
               ", rn='" + rn + '\'' +
               ", srf='" + srf + '\'' +
               ", spare='" + spare + '\'' +
               ", rins='" + rins + '\'' +
               '}';
    }

    /**
     * 解码
     *
     * @param byteBuf
     * @param length       报文消息主体的长度（不包含头和尾）
     *                     如果包含头和尾 （-HEAD_TYPE_LENGTH -END）
     */
    @Override
    public List<PointOfSale> decoderBody(ByteBuf byteBuf,short length) throws UnsupportedEncodingException
    {
        List<PointOfSale> list = new ArrayList<>();

//        for (int i = 0; i < length / PointOfSaleConstant.UPLOAD_CONSUME_RECORD_LENGTH;i++)
        for (int i = 0; i < 10;i++)
        {
            UploadConsumeRecord uploadConsumeRecord = new UploadConsumeRecord();

            uploadConsumeRecord.ucrid = UUID.randomUUID().toString();//生成唯一编号 做RedisKey

            byteBuf.readBytes(two);         //交易记录类型

            uploadConsumeRecord.setTy(new String(two,utf8Encoding));

            byteBuf.readBytes(eight);       //终端交易流水号

            uploadConsumeRecord.setTtn(new String(eight,utf8Encoding));

            byteBuf.readBytes(eight);       //脱机交易流水号

            uploadConsumeRecord.setPsn(new String(eight,utf8Encoding));

            byteBuf.readBytes(twenty);      //票卡逻辑卡号

            uploadConsumeRecord.setIcn(new String(twenty,utf8Encoding));

            byteBuf.readBytes(sixteen);     //票卡物理卡号

            uploadConsumeRecord.setFcn(new String(sixteen,utf8Encoding));

            byteBuf.readBytes(twelve);      //上次交易设备编号

            uploadConsumeRecord.setLpid(new String(twelve,utf8Encoding));

            byteBuf.readBytes(fourteen);    //上次交易日期时间

            uploadConsumeRecord.setLtim(new String(fourteen,utf8Encoding));

            byteBuf.readBytes(twelve);      //本次交易设备编号

            uploadConsumeRecord.setPid(new String(twelve,utf8Encoding));

            byteBuf.readBytes(fourteen);    //本次交易日期时间

            uploadConsumeRecord.setTim(new String(fourteen,utf8Encoding));

            byteBuf.readBytes(eight);       //交易金额

            uploadConsumeRecord.setTf(new String(eight,utf8Encoding));

            byteBuf.readBytes(eight);       //本次余额

            uploadConsumeRecord.setBal(new String(eight,utf8Encoding));

            byteBuf.readBytes(two);         //交易类型

            uploadConsumeRecord.setTt(new String(two,utf8Encoding));

            byteBuf.readBytes(two);         //附加交易类型

            uploadConsumeRecord.setAtt(new String(two,utf8Encoding));

            byteBuf.readBytes(four);        //票卡充值交易次数

            uploadConsumeRecord.setCrn(new String(four,utf8Encoding));

            byteBuf.readBytes(four);        //票卡消费交易次数

            uploadConsumeRecord.setXrn(new String(four,utf8Encoding));

            byteBuf.readBytes(eight);       //交易认证码

            uploadConsumeRecord.setTac(new String(eight,utf8Encoding));

            byteBuf.readBytes(four);        //卡片类型

            uploadConsumeRecord.setCtp(new String(four,utf8Encoding));

            byteBuf.readBytes(eight);       //票价

            uploadConsumeRecord.setFee(new String(eight,utf8Encoding));

            byteBuf.readBytes(four);        //门槛年月

            uploadConsumeRecord.setDmon(new String(four,utf8Encoding));

            byteBuf.readBytes(two);         //公交门槛计数

            uploadConsumeRecord.setBdct(new String(two,utf8Encoding));

            byteBuf.readBytes(two);         //地铁门槛计数

            uploadConsumeRecord.setMdct(new String(two,utf8Encoding));

            byteBuf.readBytes(two);         //联乘门槛计数

            uploadConsumeRecord.setUdct(new String(two,utf8Encoding));

            byteBuf.readBytes(sixteen);     //发卡机构标识码

            uploadConsumeRecord.setIins(new String(sixteen,utf8Encoding));

            byteBuf.readBytes(four);        //城市代码

            uploadConsumeRecord.setArea(new String(four,utf8Encoding));

            byteBuf.readBytes(four);        //区域卡类型

            uploadConsumeRecord.setAct(new String(four,utf8Encoding));

            byteBuf.readBytes(two);         //区域子码

            uploadConsumeRecord.setSare(new String(two,utf8Encoding));

            byteBuf.readBytes(thirteen);    //经度

            uploadConsumeRecord.setLot(new String(thirteen,utf8Encoding));

            byteBuf.readBytes(thirteen);    //纬度

            uploadConsumeRecord.setLat(new String(thirteen,utf8Encoding));

            byteBuf.readBytes(two);         //消费密钥版本号

            uploadConsumeRecord.setCkv(new String(two,utf8Encoding));

            byteBuf.readBytes(two);         //消费密钥索引

            uploadConsumeRecord.setCki(new String(two,utf8Encoding));

            byteBuf.readBytes(two);         //算法标志

            uploadConsumeRecord.setAsign(new String(two,utf8Encoding));

            byteBuf.readBytes(eight);       //随机数

            uploadConsumeRecord.setRn(new String(eight,utf8Encoding));

            byteBuf.readBytes(twelve);      //检索参考号

            uploadConsumeRecord.setSrf(new String(twelve,utf8Encoding));

            byteBuf.readBytes(eighteen);    //备用

            uploadConsumeRecord.setSpare(new String(eighteen,utf8Encoding));

            byteBuf.readBytes(eight);       //收单机构代码

            uploadConsumeRecord.setRins(new String(eight,utf8Encoding));

            list.add(uploadConsumeRecord);
        }

        return list;
    }

    /**
     * 编码
     *
     * @param byteBuf
     */
    @Override
    public void encoderBody(ByteBuf byteBuf)
    {

    }

    /**
     * 数据存入Redis 库
     */
    @Override
    public void writeRedis()
    {
        RedisTemplate redisTemplate = (RedisTemplate)SpringContextUtils.getBean("redisTemplate");

        ListOperations listOperations = redisTemplate.opsForList();

        logger.info("当前开始时间："+System.currentTimeMillis()+"  当前线程："+Thread.currentThread().getName());

        listOperations.rightPushAll(RedisKeyAndSaveDataServiceNameEnum.UPLOAD_CONSUME_RECORD.getRedisKey(),this.pointOfSales);

        logger.info("共插入 "+this.pointOfSales.size()+" 条  当前线程："+Thread.currentThread().getName());

        logger.info("当前结束时间："+System.currentTimeMillis()+"  当前线程："+Thread.currentThread().getName());

    }
}
